package vacuum.lgadmin.jail;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;

import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.WorldCreator;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.PluginManager;

import vacuum.lgadmin.CommandData;
import vacuum.lgadmin.LGAdmin;
import vacuum.lgadmin.LGPlugin;
import vacuum.lgadmin.utils.IOUtils;

public class JailPlugin extends LGPlugin
{

	public JailPlugin(LGAdmin lga)
	{
		super(lga);
	}

	private Location jailLocation;

	private JailListener jpl;

	@Override
	public void onEnable()
	{

		log("Verifying files.");

		verify(getDataFolder() + File.separator + "players.txt");
		verify(getDataFolder() + File.separator + "config.yml");

		final YamlConfiguration config = getConfig();

		String[] nodes = {"jail.world", "jail.x", "jail.y", "jail.z"};
		for (int i = 0; i < nodes.length; i++)
		{
			if(!config.contains(nodes[i])){
				config.createSection(nodes[i]);
			}
		}



		jailLocation = new Location(lga.getServer().createWorld(new WorldCreator(config.getString("jail.world", "world"))), config.getDouble("jail.x", 0), config.getDouble("jail.y", 0), config.getDouble("jail.z", 0));

		log("Loading players.");

		jpl = new JailListener(loadJailedPlayers(), jailLocation);

		registerCommand(new CommandData("jail", "vacuum.lgaadmin.jail.jail"), new CommandExecutor()
		{

			@Override
			public boolean onCommand(CommandSender sender, Command command,
					String label, String[] args)
			{

				if(jpl.jailPlayer(lga.getServer().getPlayer(args[0]), (args.length == 2) ? args[1] : null))
					lga.getServer().broadcast(ChatColor.AQUA + (lga.getServer().getPlayer(args[0]).getName() + " was jailed" + ((args.length == 2) ? " for " + args[1] : "") + "."), Server.BROADCAST_CHANNEL_USERS);
				else
					sender.sendMessage(ChatColor.RED + " that player is already in jail!");
				return true;
			}
		});

		registerCommand(new CommandData("release", "vacuum.lgaadmin.jail.release"), new CommandExecutor()
		{

			@Override
			public boolean onCommand(CommandSender sender, Command command,
					String label, String[] args)
			{
				jpl.freePlayer(lga.getServer().getPlayer(args[0]));
				return true;
			}
		});

		registerCommand(new CommandData("setjail", "vacuum.lgaadmin.jail.set"), new CommandExecutor()
		{

			@Override
			public boolean onCommand(CommandSender sender, Command command,
					String label, String[] args)
			{
				if(sender instanceof ConsoleCommandSender){
					sender.sendMessage("You must be in-game to perform this command. You can directly manipulate jail location by modifying the config file.");
				}
				Location loc = ((Player)sender).getLocation();
				jailLocation.setX(loc.getBlockX());
				jailLocation.setY(loc.getBlockY());
				jailLocation.setZ(loc.getBlockZ());
				jailLocation.setWorld(loc.getWorld());
				config.set("jail.world", jailLocation.getWorld().getName());
				config.set("jail.x", jailLocation.getBlockX());
				config.set("jail.y", jailLocation.getBlockY());
				config.set("jail.z", jailLocation.getBlockZ());
				try
				{
					config.save(getDataFolder() + File.separator + "config.yml");
				} catch (IOException e)
				{
					e.printStackTrace();
				}
				sender.sendMessage(ChatColor.AQUA + "Location set!");
				return true;
			}
		});

		log("Registering listeners");

		PluginManager pm = lga.getServer().getPluginManager();
		pm.registerEvents(jpl, lga);
	}

	private void verify(String file)
	{
		try{
			File f= new File(file);
			if(!f.exists()){
				f.getParentFile().mkdirs();
				f.createNewFile();
			}
		} catch (Exception ex){
			ex.printStackTrace();
		}
	}

	private HashMap<String, Location> loadJailedPlayers()
	{
		HashMap<String, Location> jailed = new HashMap<String, Location>();
		try
		{
			HashMap<String, String> map = IOUtils.readHashMapStringString(new File(getDataFolder() + File.separator + "players.txt"));
			Server s = lga.getServer();
			for(String key : map.keySet()){
				String[] val = map.get(key).split("`");
				Location loc = new Location(s.createWorld(new WorldCreator(val[0])), Double.parseDouble(val[1]), Double.parseDouble(val[2]), Double.parseDouble(val[3]));
				jailed.put(key.toLowerCase(), loc);
			}
		} catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return jailed;
	}

	private void saveJailedPlayers(HashMap<String, Location> players) throws IOException
	{
		HashMap<String, String> map = new HashMap<String, String>();
		for(String key : players.keySet()){
			Location loc = players.get(key);
			String val = loc.getWorld().getName() + "`" + loc.getX() + "`" + loc.getY() + "`" + loc.getZ();
			map.put(key, val);
		}
		IOUtils.writeHashMapStringString(new File(getDataFolder() + File.separator + "players.txt"), map);
	}

	@Override
	public void onDisable()
	{
		try
		{
			log("Saving players.");
			saveJailedPlayers(jpl.getJailedPlayers());
		} catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	@Override
	public String getName()
	{
		return "LGJail";
	}

	@Override
	public String getVersion()
	{
		return "1.2.1";
	}

}
